home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol05 / 04 / pmaccess / pmserver.c < prev    next >
C/C++ Source or Header  |  1990-07-01  |  12KB  |  356 lines

  1. /* pmserver.c RHS
  2.  *
  3.  * Pm program that supplies PM services to VIO apps
  4.  *
  5.  */
  6.  
  7. #define INCL_WIN
  8. #define INCL_VIO
  9. #define INCL_AVIO
  10. #define INCL_DOS
  11. #include<os2.h>
  12. #include<mt\stdlib.h>
  13. #include<mt\process.h>
  14. #include<mt\string.h>
  15. #include<mt\stdio.h>
  16. #include"pmserver.h"
  17. #include"pmsvmsgs.h"
  18. #include"msgq.h"
  19. #include"client.h"
  20. #include"errexit.h"
  21.  
  22. #define    MAXCLIENTS    25
  23. CLIENT clients[MAXCLIENTS];
  24.  
  25. #define OBJWINDTHREADSTACK  8192
  26.  
  27. HAB     hab;
  28. HWND    PMSWinHdl;
  29. #define QMGRTHREADSTACK        2048
  30. BYTE    QMgrThreadStack[QMGRTHREADSTACK];
  31. HQUEUE  qhandle;
  32.  
  33. int main(void);
  34. MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1,
  35.     MPARAM mp2);
  36. void QMgrThread(void);
  37. USHORT QMgrFindClient(PID pid,HQUEUE *qhandle,USHORT *position);
  38.  
  39. int main(void)
  40.     {
  41.     static ULONG flFrameFlags = FCF_TASKLIST;
  42.  
  43.     static CHAR  szClientClass[] = "PMServer";
  44.     HMQ          hmq;
  45.     HWND         hwndFrame, hwndClient;
  46.     QMSG         qmsg;
  47.  
  48.     MsgQCreate(&qhandle,PMSERVERQUE);           // create OS/2 queue
  49.  
  50.     hab = WinInitialize(0);                     // initialize window
  51.  
  52.     if(_beginthread(QMgrThread,QMgrThreadStack, // start qmgr thread
  53.             sizeof(QMgrThreadStack),NULL) == -1)
  54.         error_exit(0,"_beginthread(QMgrThread)");
  55.  
  56.     hmq = WinCreateMsgQueue(hab, 0);            // create msg queue
  57.  
  58.                                                 // register window
  59.     WinRegisterClass(hab, szClientClass, ClientWndProc, 0L, 0);
  60.  
  61.                                                 // create window
  62.     hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
  63.         0L, &flFrameFlags, szClientClass, NULL, 0L, NULL, 0L,
  64.         &hwndClient);
  65.  
  66.     while(WinGetMsg(hab, &qmsg, NULL, 0, 0))    // process messages
  67.         WinDispatchMsg(hab, &qmsg);
  68.  
  69.     WinDestroyWindow(hwndFrame);                // destroy window
  70.     WinDestroyMsgQueue(hmq);                    // destroy msg queue
  71.     WinTerminate(hab);                          // terminate window
  72.     return 0;
  73.     }
  74.  
  75. MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1,
  76.     MPARAM mp2)
  77.     {
  78.     SEL             ClipTextSel;
  79.     PVOID           temp1,temp2;
  80.     USHORT          len;
  81.     PCH             temp3;
  82.     USHORT          fmtInfo;
  83.  
  84.     switch(msg)
  85.         {
  86.         // ************* Create processing **********
  87.         case WM_CREATE:
  88.             PMSWinHdl = hwnd;
  89.             return 0;
  90.  
  91.         // **************Clipboard handling *********
  92.  
  93.         case PMSV_COPY:                         // put data in Clpbrd
  94.             DosAllocSeg(SHORT1FROMMP(mp2),&ClipTextSel,SEG_GIVEABLE);
  95.             temp1 = MAKEP(ClipTextSel,0);
  96.             temp2 = PVOIDFROMMP(mp1);
  97.             memmove(temp1,temp2,SHORT1FROMMP(mp2));
  98.             temp1 = temp2 = NULL;
  99.  
  100.             WinOpenClipbrd(hab);                // open the clipboard
  101.             WinEmptyClipbrd(hab);               // empty it
  102.                                                 // put new data in 
  103.             WinSetClipbrdData(hab, (ULONG)ClipTextSel, CF_TEXT,
  104.                 CFI_SELECTOR);
  105.             WinCloseClipbrd(hab);               // close clipboard
  106.             return 0;
  107.  
  108.         case PMSV_PASTE:                        // get frm Clpbrd
  109.             WinOpenClipbrd(hab);                // open the clipboard
  110.             ClipTextSel = (SEL)WinQueryClipbrdData(hab, CF_TEXT);
  111.             if(ClipTextSel)                     // if data in it
  112.                 {
  113.                 temp3 = temp1 = MAKEP(ClipTextSel,0);
  114.                 for( len = 0; temp3[len]; len++); // get data length
  115.                 len++;                          // include the NULL
  116.                                                 // send data 
  117.                 MsgQSend(SHORT1FROMMP(mp1),temp1,len,
  118.                     PMS_CLPBRD_DATA);
  119.                 }
  120.             else                                // nothing in it
  121.                 MsgQSend(SHORT1FROMMP(mp1),NULL,0,PMS_CLPBRD_EMPTY);
  122.             WinCloseClipbrd(hab);
  123.             return 0;
  124.  
  125.         case PMSV_PASTE_MSG:                    // client query
  126.                                                 // tell client 
  127.             MsgQSend(SHORT1FROMMP(mp1),NULL,0,
  128.                     (WinQueryClipbrdFmtInfo(hab,CF_TEXT,&fmtInfo) ?
  129.                     PMS_CLPBRD : PMS_CLPBRD_EMPTY));
  130.             return 0;
  131.  
  132.         case PMSV_THREAD_TERMINATE:             // obj window term
  133.             {
  134.             int i;
  135.  
  136.             for( i = 0; i < MAXCLIENTS; i++)
  137.                 if(clients[i].hwnd == HWNDFROMMP(mp1))
  138.                     {
  139.                     clients[i].isddeclient = FALSE;
  140.                     free(clients[i].threadstack);
  141.                     clients[i].hwnd = NULL;
  142.                     clients[i].appname[0] = '\0';
  143.                     clients[i].topicname[0] = '\0';
  144.                     break;
  145.                     }
  146.             }
  147.             return 0;
  148.  
  149.         case WM_CLOSE:                          // server terminate
  150.             {
  151.             int i;
  152.  
  153.             for(i = 0; i < MAXCLIENTS; i++)
  154.                 if(clients[i].kclient_pid)
  155.                     {
  156.                     if(clients[i].isddeclient)  // notify obj window
  157.                         WinPostMsg(clients[i].hwnd,PMSV_TERMINATE,
  158.                             0,0);
  159.                                                 // notify client
  160.                     MsgQSend(clients[i].qhandle,NULL,0,
  161.                         PMS_SERVER_TERM);
  162.                     }                           // notify Qmgr
  163.             MsgQSend(qhandle,NULL,0,PMS_SERVER_TERM);
  164.             WinPostMsg(hwnd,WM_QUIT,0,0);
  165.             return 0;
  166.             }
  167.  
  168.         }
  169.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  170.     }
  171.  
  172.  
  173. void QMgrThread(void)
  174.     {
  175.     PVOID   msgdata = NULL;
  176.     USHORT  msg,i,msgsize,position,server = TRUE;
  177.     HQUEUE  temphandle;
  178.     PBYTE   tempname;
  179.     PID     temppid;
  180.  
  181.     memset(clients,0,sizeof(clients));
  182.  
  183.     while(server)
  184.         {
  185.         temppid = 0;
  186.         MsgQGet(qhandle, &msgdata, &msgsize, &msg);
  187.  
  188.         switch(msg)
  189.             {
  190.             case PMS_CLPBRD_COPY:
  191.                 break;
  192.             case PMS_INIT:
  193.             case PMS_TERMINATE:
  194.             case PMS_CLPBRD_QUERY:
  195.             case PMS_CLPBRD_PASTE:
  196.             default:
  197.                 temppid = (msgdata ? CLIENTDATAMSG(msgdata)->pid :
  198.                     0);
  199.                 break;
  200.             }
  201.  
  202.         if(msg != PMS_INIT) // if client not registered, forget it
  203.             if(!QMgrFindClient(temppid,&temphandle,&position))
  204.                 continue;
  205.  
  206.         switch(msg)
  207.             {
  208.             case PMS_INIT:  // client is initializing to use server
  209.                 if(msgdata)                     // if valid message
  210.                     {
  211.                     tempname = CLIENTDATAMSG(msgdata)->qname;
  212.                     if(*tempname)               // client queue
  213.                         MsgQOpen(&temphandle,tempname);
  214.  
  215.                                                 // find open slot
  216.                     for( i = 0; i < MAXCLIENTS &&
  217.                         clients[i].kclient_pid; i++);
  218.                     if(i == MAXCLIENTS)            // no slots found
  219.                         {
  220.                         if(temphandle)
  221.                             MsgQSend(temphandle,NULL,0,PMS_NO_INIT);
  222.                         }
  223.                     else                        // got open slot
  224.                         {
  225.                         clients[i].kclient_pid = temppid;
  226.                         if(temphandle)
  227.                             {
  228.                             clients[i].qhandle = temphandle;
  229.                             MsgQSend(temphandle,NULL,0,PMS_INIT_ACK);
  230.                             }
  231.                         }
  232.                     }
  233.                 tempname = NULL;
  234.                 break;
  235.  
  236.             case PMS_TERMINATE:
  237.                     // client terminating or not using PMServer
  238.                     // if not last slot, shift down 1
  239.                 if(position != MAXCLIENTS-1)
  240.                     memmove(&clients[position],&clients[position+1],
  241.                         (sizeof(CLIENT)*(MAXCLIENTS-position-1)));
  242.                                             // clear last slot
  243.                 memset(&clients[MAXCLIENTS-1],0,sizeof(CLIENT));
  244.                 break;
  245.  
  246.             case PMS_SERVER_TERM:
  247.                     // server is terminating, close it up!
  248.                 server = FALSE;
  249.                 break;
  250.  
  251.  
  252.             // ************** Clipboard Handling
  253.  
  254.             case PMS_CLPBRD_COPY:  // client has data for Clipboard
  255.                 WinPostMsg(PMSWinHdl,PMSV_COPY,MPFROMP(msgdata),
  256.                         MPFROMSHORT(msgsize));
  257.                 msgdata = NULL;
  258.                 break;
  259.  
  260.             case PMS_CLPBRD_QUERY:
  261.                     // client query: if something's in the clipboard
  262.                 WinPostMsg(PMSWinHdl,PMSV_PASTE_MSG,
  263.                     MPFROMSHORT(temphandle),NULL);
  264.                 break;
  265.  
  266.             case PMS_CLPBRD_PASTE:
  267.                     // client requesting copy of the Clipboard data
  268.                 WinPostMsg(PMSWinHdl,PMSV_PASTE,
  269.                     MPFROMSHORT(temphandle),NULL);
  270.                 break;
  271.  
  272.  
  273.             // ************** DDE Handling
  274.  
  275.             case PMS_DDE_INIT:
  276.                     // client requests DDE client services
  277.                 {
  278.                 PCLIENT pclient = &clients[position];
  279.                 PBYTE p = (PBYTE)CLIENTDATAMSG(msgdata)->qname;
  280.  
  281.                 pclient->threadstack = malloc(OBJWINDTHREADSTACK);
  282.                 pclient->isddeclient = TRUE;
  283.                 pclient->hwndpmserver = PMSWinHdl;
  284.                 strcpy(pclient->appname,p);
  285.                 p += (strlen(p)+1);
  286.                 strcpy(pclient->topicname,p);
  287.  
  288.                 _beginthread(CreateClient,pclient->threadstack,
  289.                     OBJWINDTHREADSTACK,pclient);
  290.                 }
  291.                 break;
  292.  
  293.             case PMS_DDE_REQUEST:
  294.             case PMS_DDE_ADVISE:
  295.                     // client wants a data update
  296.                 {
  297.                 ITEMREQ itemreq;
  298.                 PCLIENT pclient = &clients[position];
  299.                 PBYTE p = (PBYTE)CLIENTDATAMSG(msgdata)->qname;
  300.  
  301.                 strcpy(itemreq.item,p);
  302.                 itemreq.value[0] = '\0';
  303.                 if(pclient->isddeclient)
  304.                     WinPostMsg(pclient->hwnd,
  305.                         (msg == PMS_DDE_REQUEST ?
  306.                         PMSV_REQUEST : PMSV_ADVISE),
  307.                         PMSWinHdl, &itemreq);
  308.                 }
  309.                 break;
  310.  
  311.             case PMS_DDE_TERMINATE:
  312.                 {
  313.                 PCLIENT pclient = &clients[position];
  314.  
  315.                 WinPostMsg(pclient->hwnd,WM_DDE_TERMINATE,0L,0L);
  316.                 break;
  317.                 }
  318.  
  319.             default:
  320.                 // unknown message rec'd, notify client 
  321.                 MsgQSend(temphandle,NULL,0,PMS_MSG_UNKNOWN);
  322.                 break;
  323.             }
  324.         if(msgdata)
  325.             DosFreeSeg(SELECTOROF(msgdata));
  326.         msgdata = NULL;
  327.         }
  328.     }
  329.  
  330. // finds PMServer client and qhandle in table
  331. USHORT QMgrFindClient(PID pid,HQUEUE *qhandle,USHORT *position)
  332.     {
  333.     USHORT  i;
  334.  
  335.     for( i = 0; i < MAXCLIENTS; i++)
  336.         if(clients[i].kclient_pid == pid)
  337.             {
  338.             *qhandle = clients[i].qhandle;
  339.             *position = i;
  340.             return TRUE;
  341.             }
  342.     return FALSE;
  343.     }
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.